require 'rubygems'
require 'nicovideo'
require 'logger'
require 'yaml'

module Nicovideo
  class Base
    attr_reader :agent
    def get_published_at(video_id)
      get_videopage(video_id).published_at
    end
  end
end

#<div class="cmn_thumb_frm">
#<div class="cmn_thumb_L">
#...
#<p><a href="watch/sm???????"><img class="thumb_img" /></a></p>
#...
#<p class="TXT10">
#<strong>58分40秒</strong>
#<br />
#再生：
#<strong>85,055</strong>
#<br />
#コメント：
#<strong>223,362</strong>
#<br />
#マイリスト：
#<strong>2,120</strong>
#</p>
#</div>
#<div class="cmn_thumb_R">
#<p class="TXT12">
#<a class="video" href="watch/sm???????">タイトル</a>
#<br />
#コメント
#</p>
#...
#</div>
#</div>
def search(nv, keyword)
  url="http://www.nicovideo.jp/search/#{URI.escape(keyword.toutf8)}?sort=f"
  page = nv.agent.get(url)
  doc = Hpricot(page.body)
  doc.search("div[@class='cmn_thumb_L']").map do |div|
    str = div.search("p[@class='TXT10']/strong")
    {'video_url' => div.search('p/a')[0]['href'],
     'time' => str[0].inner_html.scan(/\d+/).inject(0) do |s,t| s = s * 60 + t.to_i end, 
     'viewed' => str[1].inner_html.split(',').join.to_i,
     'comment' => str[2].inner_html.split(',').join.to_i,
     'mylist'  => str[3].inner_html.split(',').join.to_i
    }
  end
end

def add_mylist(nv, video_url, group_id)
  nv.agent.get(video_url)
  nv.agent.post(video_url, {'mylist' => 'add', 'group_id' => group_id, 'mylist_add' => URI.escape('登録')})
end

def main
  yaml = 'nico.yaml'
  yaml = ARGV[0] if ARGV.length > 0 
  unless File.exist? yaml
    STDERR.print "ruby nicotrigger.rb nico.yaml"
    exit
  end
  
  setting = YAML.load_file(yaml)
  
  common = setting['common']
  mail = common['mail']
  pass = common['pass']
  log = common['log'] || 'nicotrigger.log'
  group_id = common['group_id']
  list = setting['list']
  
  $logger = Logger.new(log)
  $logger.level = Logger::DEBUG
  nv = Nicovideo::Base.new(mail, pass)
  nv.agent.log = $logger
  now = Time.now
  videoreg = /watch\/(sm[0-9]+)/
  list.each do |s|
    $logger.debug(s)
    next unless s['wday'] == now.wday
    videos = search(nv, s['keyword']).select do |v| 
      #動画の長さが合うものを絞込み
      v['time'] > s['min_minutes'] * 60 && v['time'] < s['max_minutes'] * 60
    end.select do |v|
      begin 
        #投稿時刻からの経過時間が閾値以内のものを絞り込み
        id = v['video_url'].match(videoreg)[1]
        tm = nv.get_published_at(id)
        sleep 10
        $logger.debug("#{now - tm} seconds passed.")
        now - tm < s['recent_hours'] * 60 * 60
      rescue 
        $logger.warn("#{$!.to_s.toutf8} #{$!.backtrace}") if $logger
        if $!.is_a?(Nicovideo::Forbidden)
          nv = Nicovideo::Base.new(mail, pass)
          nv.agent.log = $logger
          nv.agent.login
          sleep 10
        end
        false
      end
    end.sort do |x,y| 
      #再生回数の多い順に並べる
      y['viewed'] <=> x['viewed']
    end
    $logger.debug(videos)
    add_mylist(nv, videos[0]['video_url'], group_id) if videos.length > 0
  end
end

if __FILE__ == $0
  begin
    main
  rescue
    $logger.warn("#{$!.to_s.toutf8} #{$!.backtrace}") if $logger
  end
end
